<template>
  <div class="custom-table-container" v-loading="loading">
    <el-table ref="table" :data="listData" v-bind="$attrs" v-on="$listeners">
      <slot />
    </el-table>
    <div
      class="table-pagination"
      v-if="isPagination && pagination.total"
      :class="{ extra: $slots.extra }"
    >
      <slot name="extra" />
      <el-pagination
        class="pagination"
        background
        :current-page.sync="pagination.page"
        :pager-count="5"
        :page-sizes="sizes"
        :page-size="pagination.limit"
        :total="pagination.total"
        layout="total, sizes, prev, pager, next"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script>
export default {
  props: {
    // 请求地址
    request: {
      type: Function
    },
    // 请求参数
    params: {
      type: Object,
      default: () => {}
    },
    isRequest: {
      type: Boolean,
      default: true
    },
    limit: {
      type: Number,
      default: 10
    },
    sizes: {
      type: Array,
      default: () => [10, 20, 50, 100] // 页面选项设置
    },
    // 是否需要缓存页码
    isCachePage: {
      type: Boolean,
      default: false
    },
    // 是否展示底部分页
    isPagination: {
      type: Boolean,
      default: true
    },
    data: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      listData: [],
      resultData: {},
      pagination: {
        total: 0, // 总条数
        page: 1 // 页码
      },
      loading: false,
      extendSource: {},
      tab: '' //tab切换
    }
  },
  watch: {
    limit: {
      handler(val) {
        this.pagination.limit = val
      },
      immediate: true
    },
    data: {
      handler(val) {
        this.listData = val
        this.pagination.total = val.length
      },
      immediate: true,
      deep: true
    },
    '$route.query': {
      handler(val) {
        if (this.isCachePage) {
          this.pagination = {
            ...this.pagination,
            page: +val?.page || 1,
            limit: +val?.limit || this.limit
          }
        }
        if (this.isRequest) {
          this.getList()
        }
      },
      immediate: true,
      deep: true
    },
    immediate: true
  },
  mounted() {
    if (!this.listData) {
      this.getList()
    }
  },
  created() {
    this.tab = this.$route.query.tab
    if (this.isRequest && !this.isCachePage) {
      // this.getList()
    }
  },
  methods: {
    getList(type) {
      return new Promise((resolve, reject) => {
        const defaultParams = ['code', 'count', 'data', 'msg']
        if (type === 'search') {
          this.pagination.page = 1
        } else {
          // 如果地址栏有页码 并且需要缓存页码
          if (this.$route.query.limit && this.isCachePage) {
            this.pagination.page = +this.$route.query.page
          }
        }
        if (this.request) {
          this.loading = true
          const { page, limit } = this.pagination
          this.$nextTick(async () => {
            const res = await this.request({
              ...this.params,
              page,
              limit
            }).catch(err => {
              reject(err)
              this.loading = false
            })
            if (res.code == 0) {
              this.listData = res.data?.data || res.data
              this.resultData = res

              const extendData = {}
              Object.keys(res).forEach(key => {
                if (!defaultParams.includes(key)) {
                  extendData[key] = res[key]
                }
              })
              this.extendSource = extendData
              this.$emit('success', res)
              this.pagination.total = res.count || res.total
              this.loading = false
              resolve(res)
            } else {
              this.loading = false
              reject(res)
            }
          })
        } else {
          throw Error('request不能为空')
        }
      })
    },

    resetTable(params = {}) {
      return new Promise(resolve => {
        this.$emit('update:params', { ...this.defaultParams, ...params })
        this.pagination.page = 1
        this.$nextTick(async () => {
          await this.getList('reset')
          resolve()
        })
      })
    },
    // 更改每页数量
    handleSizeChange(val) {
      let page = this.$route.query.page
      this.pagination.limit = val
      this.pagination.page = 1
      if (this.pagination.total <= val) {
        page = 1
      }
      if (this.isCachePage) {
        this.$router.push({
          query: {
            ...this.$route.query,
            limit: val,
            page: 1
          }
        })
        if (!this.isCachePage) {
          this.getList()
        }
      } else {
        this.$nextTick(() => {
          this.getList()
        })
      }
    },
    // 翻页
    handleCurrentChange(val) {
      if (this.isCachePage) {
        this.$router.push({
          query: {
            ...this.$route.query,
            page: val
          }
        })
        if (!this.isCachePage) {
          this.getList()
        }
      } else {
        this.$nextTick(() => {
          this.getList()
        })
      }
      this.pagination.page = val
    }
  }
}
</script>

<style lang="scss" scoped>
.table-pagination {
  &.extra {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  padding: 16px 0 0;
  text-align: right;
}
</style>
